import {
  IconEdit,
  IconRobot,
  IconTrash,
  IconUser
} from '@tabler/icons-react';
import { type FC, memo, useContext, useEffect, useRef, useState } from 'react';

import { updateConversation } from '@/utils/app/conversation';

import { type Message } from '@/types/chat';

import HomeContext from '@/pages/api/home/home.context';

import { AssistantChatMessage } from './AssistantChatMessage';

export interface Props {
  message: Message
  messageIndex: number
  onUpdateUserMessage: (editedMessage: Message) => void
  onUpdateAssistantMessage: (editedMessage: Message) => Promise<void>
  onUpdateAssumptions: (message: Message, updatedAssumptions: string) => Promise<void>
}

export const ChatMessage: FC<Props> = memo(({ message, onUpdateUserMessage, onUpdateAssistantMessage, onUpdateAssumptions }) => {
  const {
    state: { selectedConversation, conversations },
    dispatch: homeDispatch
  } = useContext(HomeContext);

  const [isEditing, setIsEditing] = useState<boolean>(false);
  const [isTyping, setIsTyping] = useState<boolean>(false);
  const [messageContent, setMessageContent] = useState(message.content);

  const textareaRef = useRef<HTMLTextAreaElement>(null);

  const toggleEditing = () => {
    setIsEditing(!isEditing);
  };

  const handleInputChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {
    setMessageContent(event.target.value);
    if (textareaRef.current) {
      textareaRef.current.style.height = 'inherit';
      textareaRef.current.style.height = `${textareaRef.current.scrollHeight}px`;
    }
  };

  const handleEditMessage = () => {
    if (message.content !== messageContent) {
      if (selectedConversation) {
        onUpdateUserMessage({ ...message, content: messageContent });
      }
    }
    setIsEditing(false);
  };

  const handleDeleteMessage = () => {
    if (!selectedConversation) return;

    const { messages } = selectedConversation;
    const findIndex: number = messages.findIndex((elm) => elm === message);

    if (findIndex < 0) return;

    if (
      findIndex < messages.length - 1 &&
      messages[findIndex + 1].role === 'assistant'
    ) {
      messages.splice(findIndex, 2);
    } else {
      messages.splice(findIndex, 1);
    }
    const updatedConversation = {
      ...selectedConversation,
      messages
    };

    const { single, all } = updateConversation(
      updatedConversation,
      conversations
    );
    homeDispatch({ field: 'selectedConversation', value: single });
    homeDispatch({ field: 'conversations', value: all });
  };

  const handlePressEnter = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
    if (e.key === 'Enter' && !isTyping && !e.shiftKey) {
      e.preventDefault();
      handleEditMessage();
    }
  };

  // const copyOnClick = () => {
  //   if (!navigator.clipboard) return;

  //   navigator.clipboard.writeText(message.content).then(() => {
  //     setMessageCopied(true);
  //     setTimeout(() => {
  //       setMessageCopied(false);
  //     }, 2000);
  //   });
  // };

  useEffect(() => {
    setMessageContent(message.content);
  }, [message.content]);

  useEffect(() => {
    if (textareaRef.current) {
      textareaRef.current.style.height = 'inherit';
      textareaRef.current.style.height = `${textareaRef.current.scrollHeight}px`;
    }
  }, [isEditing]);

  return (
    <div
      className={`group md:px-4 ${message.role === 'assistant'
        ? 'border-b border-black/10 bg-gray-50 text-gray-800 dark:border-gray-900/50 dark:bg-[#444654] dark:text-gray-100'
        : 'border-b border-black/10 bg-white text-gray-800 dark:border-gray-900/50 dark:bg-[#343541] dark:text-gray-100'
        }`}
      style={{ overflowWrap: 'anywhere' }}
    >
      <div className="relative m-auto flex p-4 text-base md:max-w-2xl md:gap-6 md:py-6 lg:max-w-2xl lg:px-0 xl:max-w-3xl">
        <div className="min-w-[40px] text-right font-bold">
          {message.role === 'assistant'
            ? (
              <IconRobot size={30} />
              )
            : (
              <IconUser size={30} />
              )}
        </div>

        <div className="prose mt-[-2px] w-full dark:prose-invert">
          {message.role === 'user'
            ? (
              <div className="flex w-full">
                {isEditing
                  ? (
                    <div className="flex w-full flex-col">
                      <textarea
                        ref={textareaRef}
                        className="w-full resize-none whitespace-pre-wrap border-none dark:bg-[#343541]"
                        value={messageContent}
                        onChange={handleInputChange}
                        onKeyDown={handlePressEnter}
                        onCompositionStart={() => { setIsTyping(true); }}
                        onCompositionEnd={() => { setIsTyping(false); }}
                        style={{
                          fontFamily: 'inherit',
                          fontSize: 'inherit',
                          lineHeight: 'inherit',
                          padding: '0',
                          margin: '0',
                          overflow: 'hidden'
                        }}
                      />

                      <div className="mt-10 flex justify-center space-x-4">
                        <button
                          className="h-[40px] rounded-md bg-blue-500 px-4 py-1 text-sm font-medium text-white enabled:hover:bg-blue-600 disabled:opacity-50"
                          onClick={handleEditMessage}
                          disabled={messageContent.trim().length <= 0}
                        >
                          {'Save & Submit'}
                        </button>
                        <button
                          className="h-[40px] rounded-md border border-neutral-300 px-4 py-1 text-sm font-medium text-neutral-700 hover:bg-neutral-100 dark:border-neutral-700 dark:text-neutral-300 dark:hover:bg-neutral-800"
                          onClick={() => {
                            setMessageContent(message.content);
                            setIsEditing(false);
                          }}
                        >
                          {'Cancel'}
                        </button>
                      </div>
                    </div>
                    )
                  : (
                    <div className="prose whitespace-pre-wrap dark:prose-invert flex-1">
                      {message.content}
                    </div>
                    )}

                {!isEditing && (
                  <div className="md:-mr-8 ml-1 md:ml-0 flex flex-col md:flex-row gap-4 md:gap-1 items-center md:items-start justify-end md:justify-start">
                    <button
                      className="invisible group-hover:visible focus:visible text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-300"
                      onClick={toggleEditing}
                    >
                      <IconEdit size={20} />
                    </button>
                    <button
                      className="invisible group-hover:visible focus:visible text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-300"
                      onClick={handleDeleteMessage}
                    >
                      <IconTrash size={20} />
                    </button>
                  </div>
                )}
              </div>
              )
            : (<AssistantChatMessage
              messageContent={messageContent}
              onUpdateAssistantMessage={onUpdateAssistantMessage}
              onUpdateAssumptions={onUpdateAssumptions}
            />)
          }
        </div>
      </div>
    </div>
  );
});
ChatMessage.displayName = 'ChatMessage';
